/*
 * SemLib.h
 *
 *  Created on: 2010-01-11
 *      Author: Maciej Skrzypkowski
 */

#ifndef SEMLIB_H_
#define SEMLIB_H_
#include <string>
#include <stdlib.h>
#include <map>
#include <sstream>
#include <time.h>
#include <string.h>
#include "tcpconnection.h"
#include "messages.h"
#include "Log.h"
#include "Receiver.h"



/*
 * Klasa typu sigleton, udostępnia metody komunikujące się
 * z serwerami semaforów - pozwalające na wykonanie
 * potrzebnych operacji na semaforach.
 */
class SemLib {
public:
	static SemLib *instance();
	//otwiera nowe połączenie z kolejnym serwerem nie zamykając poprzednich
	bool connect(const char *serverName);

	//zamyka połączenie z serwerem
	bool disconnect(const char *serverName);

	//tworzy nowy semafor o zadanej nazwie, na zadanym serwerze
	void createSemaphore(const char* semaphoreName, const char* serverName);

	//usuwa semafor o zadanej nazwie z zadanego serwera, wywoływana niejawnie
	void deleteSemaphore(const char* semaphoreName, const char* serverName);

	//operacja opuszczenia semafora o zadanej nazwie na zadanym serwerze
	void pSemaphore(const char* semaphoreName, const char* serverName = NULL);

	//operacja podniesienie semafora o zadanej nazwie na zadanym serwerze
	void vSemaphore(const char* semaphoreName, const char* serverName);

	friend class Receiver;

protected:
	SemLib();
	virtual ~SemLib();

private:
	/*
	 * Lista połączeń z serwerami.
	 */
	std::map<std::string, TCPConnection* > connectionMap;
	/*
	 * Lista wątków odbierających wiadomości.
	 */
	std::map<std::string, Receiver* > receiversMap;


	/*
	 * wysyła info do serwera z uwzględnieniem pingów i timeoutów
	 * oczekuje na odpowiedź
	 * jeśli nie udało się wysłać to zwróć false
	 */
	bool send(TCPConnection* conn, char type, String semName);

	bool sendPing(TCPConnection* conn);

	/*
	 * Kasuje rozłączony serwer z listy.
	 */
	void deleteServer(String serverName);


	/*
	 * Sprawdza czy klient jest połączony z serwerem.
	 */
	bool checkConnection(String serverName) {
		if (connectionMap.find(serverName) == connectionMap.end()) {
			Log::instance()->warn("Klient nie jest połączony z serwerem: "+serverName);
			return false;
		}
		return true;
	}

    static SemLib *inst;
    char* clientName;



};

#endif /* SEMLIB_H_ */
